package com.whjfxx.terminal.biz.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.whjfxx.terminal.biz.enums.YesNoEnum;
import com.whjfxx.terminal.biz.mapper.PoAppMapper;
import com.whjfxx.terminal.biz.mapper.PoFuncMapper;
import com.whjfxx.terminal.biz.mapper.PoTerminalMapper;
import com.whjfxx.terminal.biz.param.FuncPageParam;
import com.whjfxx.terminal.biz.param.FuncParam;
import com.whjfxx.terminal.biz.param.SearchParam;
import com.whjfxx.terminal.biz.service.PoFuncService;
import com.whjfxx.terminal.biz.service.PoTerminalService;
import com.whjfxx.terminal.biz.vo.FuncVo;
import com.whjfxx.terminal.entity.PoApp;
import com.whjfxx.terminal.entity.PoFunc;
import com.whjfxx.terminal.entity.PoTerminal;
import com.whjfxx.terminal.exceptions.BizException;
import com.whjfxx.terminal.utils.BeanUtils;
import com.whjfxx.terminal.utils.PageUtils;
import com.whjfxx.terminal.utils.QueryUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * Created by b.c on 2022/6/7 16:28
 */
@Service
public class PoFuncServiceImpl extends ServiceImpl<PoFuncMapper, PoFunc> implements PoFuncService {

    @Autowired
    PoAppMapper poAppMapper;

    @Autowired
    PoTerminalMapper poTerminalMapper;

    @Override
    public Page<FuncVo> pageList(SearchParam<FuncPageParam> searchParam) {
        if (null == searchParam.getSearchParams()) {
            return PageUtils.convertEmpty(searchParam);
        }
        LambdaQueryWrapper<PoFunc> wrapper = new LambdaQueryWrapper<>();
        QueryUtil.search(searchParam, FuncPageParam.class, (pageParam) -> {
            wrapper.eq(PoFunc::getAppId, pageParam.getAppId());
            if (StringUtils.isNotBlank(pageParam.getFuncName())) {
                wrapper.like(PoFunc::getFuncName, pageParam.getFuncName());
            }
            if (StringUtils.isNotBlank(pageParam.getToken())) {
                wrapper.like(PoFunc::getToken, pageParam.getToken());
            }
        });
        this.page(searchParam, wrapper);
        if (CollectionUtils.isEmpty(searchParam.getRecords())) {
            return PageUtils.convertEmpty(searchParam);
        }

        Page<PoFunc> page = PageUtils.buildPage(searchParam);

        List<Long> appIds = page.getRecords().stream().map(PoFunc::getAppId).collect(Collectors.toList());
        List<PoApp> poApps = this.poAppMapper.selectBatchIds(appIds);
        Map<Long, PoApp> poAppMap = poApps.stream().collect(Collectors.toMap(PoApp::getId, Function.identity()));
        return PageUtils.convert(page, FuncVo.class, (src, target) -> {
            PoApp poApp = poAppMap.get(src.getAppId());
            if (Objects.nonNull(poApp)) {
                target.setAppName(poApp.getAppName());
            }
        });
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void insertSave(FuncParam param) {
        // 校验 在同一个应用下，功能名不能重复
        PoFunc poFunc = this.baseMapper.selectByAppIdAndFuncName(param.getAppId(), param.getFuncName());
        if (Objects.nonNull(poFunc)) {
            throw BizException.build("该应用下功能名已经存在已经存在");
        }
        poFunc = new PoFunc();
        BeanUtils.copyProperties(param, poFunc);
        poFunc.setStatus(YesNoEnum.YES.status);
        String token = UUID.randomUUID().toString().toLowerCase().replaceAll("-","");
        poFunc.setToken(token);
        poFunc.setCreateTime(LocalDateTime.now());
        poFunc.setUpdateTime(LocalDateTime.now());
        this.save(poFunc);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateSave(FuncParam param) {
        // 校验 在同一个应用下，功能名不能重复
        PoFunc poFunc = this.baseMapper.selectByAppIdAndFuncName(param.getAppId(), param.getFuncName());
        if (Objects.nonNull(poFunc) && ! poFunc.getId().equals(param.getId())) {
            throw BizException.build("该应用下功能名已经存在已经存在");
        }
        PoFunc func = this.baseMapper.selectById(param.getId());
        if(Objects.isNull(func)) {
           throw BizException.build("功能信息不存在");
        }
        BeanUtils.copyProperties(param, func);
        func.setUpdateTime(LocalDateTime.now());
        this.baseMapper.updateById (func);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(Long id) {
        if (Objects.isNull(id)) {
            return;
        }
        LambdaQueryWrapper<PoTerminal> wrapper = new LambdaQueryWrapper();
        wrapper.eq(PoTerminal::getFuncId, id);
        int i = poTerminalMapper.selectCount(wrapper);
        if (i > 0) {
            throw BizException.build("功能下存在设备信息, 无法删除");
        }
        this.baseMapper.logicDelete(id, LocalDateTime.now());
    }
}
